package com.czeczek.indicators.impl;

import java.math.BigDecimal;
import java.util.LinkedList;

import com.czeczek.domain.IndicatorQuote;
import com.czeczek.domain.Quote;
import com.czeczek.domain.exceptions.IndicatorParameterException;
import com.czeczek.domain.exceptions.IndicatorParameterException.ErrorType;
import com.czeczek.indicators.AbstractIndicator;

/**
 * Implementation of Simple Moving Average indicator
 * It requires following parameters:
 * <ul>
 * <li>length - amount of days to compute SMA
 * </ul>
 * @author mczeczko
 *
 */
public class SMA extends AbstractIndicator {
	
	public final static String LENGTH_PARAM = "length";
	
	private BigDecimal length;

	public IndicatorQuote execute(LinkedList<Quote> data, Quote processedItem) {
		if (data.size() > 0) {
			int currentIdx = 0;
			int startIdx = 0;
			while (currentIdx < data.size()) {
				startIdx = currentIdx - length.intValue() + 1;
				if (startIdx >= 0) {
					processWindow(data, currentIdx, startIdx);
				}
				currentIdx++;
			}
		}
		
		return null;
	}
	
	private void processWindow(LinkedList<Quote> data, int currentIdx, int startIdx) {
		BigDecimal sum = BigDecimal.ZERO;
		for(int idx=startIdx; idx<=currentIdx; idx++) {
			sum.add(data.get(idx).getClosePrice());
		}
		IndicatorQuote indicator = new IndicatorQuote(data.get(currentIdx));
		indicator.setValue(sum.equals(BigDecimal.ZERO) ? BigDecimal.ZERO : sum.divide(length));
		data.set(currentIdx, indicator);
	}

	@Override
	public void setParameter(String name, BigDecimal value) throws Exception {
		if (name.equalsIgnoreCase(LENGTH_PARAM)) {
			if (value.stripTrailingZeros().scale() == 0) { //check if it's integer value
				length = value;
			} else {
				throw new IndicatorParameterException(ErrorType.WRONG_PARAMETER_VALUE);
			}
		} else {
			throw new IndicatorParameterException(ErrorType.WRONG_PARAMETER_NAME);
		}
	}

}
